package com.example.weibowebcrawlerdemo.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.example.weibowebcrawlerdemo.pojo.Weibo;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Handler;

@Component
@Slf4j
public class WeiboUtil {

    //用作缓存的集合对象
    private List<Weibo> list = new ArrayList<>();
    //http 服务器
    private static final CloseableHttpClient client =  HttpClients.createDefault();
    //http GET请求
    private HttpGet httpGet = null;
    //http 响应结果
    private CloseableHttpResponse response = null;
    //ul 前缀
    public static final String PREFIX_URL = "https://m.weibo.cn/api/container/getIndex?containerid=100103type";
    //url 后缀
    public static final String SUFFIX_URL = "&page_type=searchall&page=";
    //爬取的页面数量,默认是5
    private int pageNum = 5;

    /**
     * setPageNum 可以主动设置需要爬取的页面数量
     * */
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }
    /**
     * 主动获取list集合
     * */
    public List<Weibo> getList() {
        return list;
    }

    /**
     * 传入一个关键字 获取到微博网页中的相关内容
     * */
    public List<Weibo> getWeiboList(String keyword) throws IOException {
        //清除遗留的数据
        this.list.clear();
        keyword = URLEncoder.encode("=1&q="+keyword, "UTF-8");

        for (int i = 1; i <= pageNum; i++) {
            httpGet = new HttpGet(PREFIX_URL + keyword + SUFFIX_URL + i);
            boolean flag = this.dispatchHttpGetData(httpGet);
            if (!flag) return list;
        }

        return list;
    }

    /**
     * 处理httpGet 响应回来的数据
     * */
    public boolean dispatchHttpGetData(HttpGet httpGet) throws IOException {

        response = client.execute(httpGet);
        //判断请求是否成功
        if (response.getStatusLine().getStatusCode() == 200){
            //将响应中的数据转换为字符串
            String responseJSON = EntityUtils.toString(response.getEntity(), "UTF-8");
            //将字符串转换为JSON格式的对象
            JSONObject jsonObject = JSONObject.parseObject(responseJSON);
            //获取JSON对象中的data对象
            JSONObject data = jsonObject.getJSONObject("data");

            //获取到data对象中的cards数组, 并对其进行遍历
            for (Object item : data.getJSONArray("cards")) {

                //将遍历出的单元转换为JSON对象
                JSONObject card = (JSONObject)JSON.toJSON(item);
                /*
                 * 微博返回的json中的页面数据大多数保存在mblog对象中,但有部分mblog是包裹在card_group数组内的,还有一部分则是直接在cards对象中的
                 * 此处就需要进行判断,根据判断结果执行不同的处理方法
                 * */
                if (card.containsKey("card_group")){
                    Weibo weibo = this.dispatchCardGroupMblog(card);
                    if (weibo !=null)  list.add(weibo);
                }
                if (card.containsKey("mblog")){
                    Weibo weibo = this.dispatchMblog(card);
                    if (weibo !=null) list.add(weibo);
                }
            }
            return true;  //表示当前页面数据爬取成功
        }
        log.error("ERROR 当前页面数据爬取失败!");
        return false;   //表示当前页面数据爬取失败
    }

    /**
    * 处理包裹在card_group数组中的mblog
    * */
    public Weibo dispatchCardGroupMblog(JSONObject obj){

        //将card_group的mblog解析并转换为数组对象
        String mblogStr = obj.getJSONArray("card_group").getJSONObject(0).getString("mblog");

        /*
        * 在微博的设计上,超话话题也是包含在card_group中的,但超话中是没有mblog,
        * 在此处进行判断,避免空指针异常
        * */
        if (mblogStr != null){
            //将mblog字符串转换为JSON对象
            JSONObject mblog = JSONObject.parseObject(mblogStr);
            return this.createWeibo(mblog);
        }
        return null;
    }

    /**
     * 处理直接的mblog
     * */
    public Weibo dispatchMblog(JSONObject obj){

        JSONObject mblog = obj.getJSONObject("mblog");

        return this.createWeibo(mblog);

    }

    /**
     * 将处理后的数据转换为一个java对象
     * */
    public Weibo createWeibo(JSONObject mblog){

        Weibo weibo = new Weibo();
        //注入一个11位数的uuid
        weibo.setId(UUIDUtil.getElevenIDCode());

        /*if (object.containsKey("page_info")){
            System.out.println("正文2: " +  object.getJSONObject("page_info").getString("content2"));
            System.out.println("内容: " + object.getString("text"));
        }else {
            System.out.println("内容: " + object.getString("text"));
        }*/
        weibo.setWid(mblog.getJSONObject("user").getString("screen_name"));
        weibo.setText(mblog.getString("text"));
        weibo.setLikeNum(mblog.getString("attitudes_count"));
        weibo.setCommentNum(mblog.getString("comments_count"));
        weibo.setForwardNum(mblog.getString("reposts_count"));
        weibo.setReleaseTime(DateUtils.StringToDateToString(mblog.getString("created_at")));

        return weibo;
    }

}
